package util;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Vector;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author Administrator
 */
public class ThreadTutil {
    /**
     * 启动n个线程同时执行n个任务 等待所有任务执行完毕后返回所有结果
     *
     * @param  每个结果下标对应传入时下标
     * @return
     * @throws InterruptedException
     */
    @SuppressWarnings("rawtypes")
    @SafeVarargs
    public static List<Object> executes(Callable<Object>... callable) throws InterruptedException {
        Objects.requireNonNull(callable);
        ExecutorService threadPool = Executors.newCachedThreadPool();
        List<Future<Object>> futures = threadPool.invokeAll(Arrays.asList(callable));
        threadPool.shutdown();
        while (true) {
            if (threadPool.isTerminated()) {
                break;
            }
        }
        return futures.stream().map(f -> {
            try {
                return f.get();
            } catch (Exception e) {
                return null;
            }
        }).collect(Collectors.toList());
    }

    /**
     * 启动多个线程执行n个任务，默认线程数量等于运行计算机上的处理器数量
     *
     * @param callables 任务列表
     *                  Djava.util.concurrent.ForkJoinPool.common.parallelism=n;配置ForkJoinPool指定线程数
     *                  System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", n);
     * @return 任务的结果集（按执行时间 先执行的在前面）
     */
    @SafeVarargs
    public static List<Object> executeJobs(Callable<Object>... callables) {
        Objects.requireNonNull(callables);
        List<Object> futures = new Vector<>();
        Stream.of(callables).parallel().forEach(r -> {
            try {
                futures.add(Callable.class.getMethod("call").invoke(r, null));
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        return futures;
    }
}
